package com.itheima.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.BaseContants;
import com.itheima.reggie.common.R;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Setmeal;
import com.itheima.reggie.entity.SetmealDish;
import com.itheima.reggie.entity.dto.SetmealDto;
import com.itheima.reggie.mapper.CategoryMapper;
import com.itheima.reggie.mapper.DishMapper;
import com.itheima.reggie.mapper.SetmealDishMapper;
import com.itheima.reggie.mapper.SetmealMapper;
import com.itheima.reggie.service.SetmealService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author:YZN
 * @date:2022/12/31
 * @description:
 */
@Service
public class SetmealServiceImpl implements SetmealService {
    @Resource
    private SetmealMapper setmealMapper;

    @Resource
    private SetmealDishMapper setmealDishMapper;

    @Resource
    private CategoryMapper categoryMapper;


    @Resource
    private RedisTemplate redisTemplate;

    @Override
    @Transactional
    public R add(SetmealDto setmealDto) {
        //todo 校验参数
        if (null == setmealDto) {
            return R.error("参数错误");
        }
        //todo 保存套餐信息到套餐中
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDto, setmeal);
        setmealMapper.insert(setmeal);

        setmealDto.getSetmealDishes().stream().forEach(item -> {
            //todo 补全套餐明细的属性
            item.setSetmealId(setmeal.getId());
            //todo 保存套餐明细到setmealDish表中
            setmealDishMapper.insert(item);
        });
        redisTemplate.delete(BaseContants.SETMEAL_SUFFIX +setmealDto.getCategoryId());

        return R.success("保存套餐成功");
    }

    @Override
    public R page(Integer page, Integer pageSize, String name) {
        //todo 参数校验
        if (page <= 0 || pageSize <= 0) {
            return R.error("参数错误");
        }
        //todo 套餐分页条件查询
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(name), Setmeal::getName, name);
        Page<Setmeal> pageInfo = new Page<>(page, pageSize);
        setmealMapper.selectPage(pageInfo, queryWrapper);
        //todo 封装参数
        Page<SetmealDto> setmealDtoPage = new Page<>();
        BeanUtils.copyProperties(pageInfo, setmealDtoPage);

        List<SetmealDto> setmealDtos = pageInfo.getRecords().stream().map(c -> {
            SetmealDto setmealDto = new SetmealDto();
            BeanUtils.copyProperties(c, setmealDto);
            LambdaQueryWrapper<SetmealDish> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SetmealDish::getDishId, c.getId());
            List<SetmealDish> setmealDishes = setmealDishMapper.selectList(wrapper);
            setmealDto.setSetmealDishes(setmealDishes);

            //todo 根据categoryId查询categoryName
            Category category = categoryMapper.selectById(setmealDto.getCategoryId());
            setmealDto.setCategoryName(category.getName());

            return setmealDto;
        }).collect(Collectors.toList());

        setmealDtoPage.setRecords(setmealDtos);


        return R.success(setmealDtoPage);
    }

    @Override
    public R findById(Long id) {
        //todo 参数校验
        if (null == id) {
            return R.error("参数错误");
        }
        SetmealDto setmealDto = new SetmealDto();
        //todo 根据id查找setmeal
        Setmeal setmeal = setmealMapper.selectById(id);
        BeanUtils.copyProperties(setmeal, setmealDto);
        //todo 根据setmealid查找setmealdish
        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SetmealDish::getSetmealId, id);
        List<SetmealDish> setmealDishes = setmealDishMapper.selectList(queryWrapper);

        setmealDto.setSetmealDishes(setmealDishes);
        return R.success(setmealDto);
    }

    @Override
    @Transactional
    public R update(SetmealDto setmealDto) {
        //todo 参数校验
        if (null == setmealDto) {
            return R.error("参数错误");
        }
        //todo 修改套餐信息
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDto, setmeal);
        setmealMapper.updateById(setmeal);
        //todo 修改套餐菜品信息
        //todo 删除原来的菜品
        LambdaUpdateWrapper<SetmealDish> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SetmealDish::getSetmealId, setmeal.getId());
        setmealDishMapper.delete(updateWrapper);
        //todo 加入修改后的套餐
        setmealDto.getSetmealDishes().stream().forEach(c -> {
            c.setSetmealId(setmeal.getId());
            setmealDishMapper.insert(c);
        });

        redisTemplate.delete(BaseContants.SETMEAL_SUFFIX+setmealDto.getCategoryId());
        return R.success("修改成功");
    }

    @Override
    public R status(Integer type, Long[] ids) {
        //todo 参数校验
        if (null == ids || null == type) {
            return R.error("参数错误");
        }
        //todo 判断是停售还是起售
        if (type == 1) {
            //起售
            Arrays.stream(ids).forEach(c -> {
                Setmeal setmeal = setmealMapper.selectById(c);
                setmeal.setStatus(1);
                setmealMapper.updateById(setmeal);
            });
            return R.success("起售成功");
        } else if (type == 0) {
            //停售
            Arrays.stream(ids).forEach(c -> {
                Setmeal setmeal = setmealMapper.selectById(c);
                setmeal.setStatus(0);
                setmealMapper.updateById(setmeal);
            });
            return R.success("停售成功");
        }
        return R.error("未知错误");
    }

    @Override
    public R delete(Long[] ids) {
        //todo 参数校验
        if (null == ids) {
            return R.error("参数错误");
        }
        Arrays.stream(ids).forEach(c -> {
            //todo 删除分类信息
            Setmeal setmeal = setmealMapper.selectById(c);
            setmealMapper.deleteById(c);
            //todo 删除分类菜品信息
            LambdaUpdateWrapper<SetmealDish> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(SetmealDish::getSetmealId, c);
            setmealDishMapper.delete(updateWrapper);

            redisTemplate.delete(BaseContants.SETMEAL_SUFFIX+setmeal.getCategoryId());
        });

        return R.success("删除成功");
    }

    @Override
    public R list(Long categoryId, Integer status) {

        List<Setmeal> list = (List<Setmeal>) redisTemplate.opsForValue().get("setmeal_"+categoryId);
        if (list == null || list.size() == 0){
            LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Setmeal::getCategoryId, categoryId);
            queryWrapper.eq(Setmeal::getStatus, status);
            queryWrapper.orderByDesc(Setmeal::getUpdateTime);

            list = setmealMapper.selectList(queryWrapper);
            redisTemplate.opsForValue().set(BaseContants.SETMEAL_SUFFIX+categoryId,list);
            redisTemplate.expire(BaseContants.SETMEAL_SUFFIX+categoryId,60, TimeUnit.MINUTES);
            System.out.println("从数据库中取套餐数据...");
        }else{
            System.out.println("从redis中取套餐数据...");
        }
        return R.success(list);

    }
}
